package cn.chiship.framework.business.core.config;

import cn.chiship.framework.common.util.SwaggerUtil;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.StringUtils;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.spring.web.plugins.Docket;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/***
 * @author: lijian
 */
@Configuration
@EnableOpenApi
public class Swagger3Config{
    /**
     * 权限模块
     */
    private static final String UPMS_CONTROLLER = "cn.chiship.framework.upms.biz.";
    /**
     * 文档模块
     */
    private static final String DOC_CONTROLLER = "cn.chiship.framework.docs.biz.";
    /**
     * 业务模块
     */
    private static final String BUSINESS_CONTROLLER = "cn.chiship.framework.business.biz.";

    /**
     * 三方模块
     */
    private static final String THIRD_CONTROLLER = "cn.chiship.framework.third.biz.";

    @Bean
    public HttpMessageConverter responseBodyConverter() {
        StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        return converter;
    }


    @Bean
    public Docket createRestApi() {
        return baseDoctor("1.1.对外开发", UPMS_CONTROLLER + "api");
    }

    @Bean
    public Docket createBaseApi() {
        return baseDoctor("2.1.基本模块", UPMS_CONTROLLER + "base.controller");
    }

    @Bean
    public Docket createBase2Api() {
        return baseDoctor("2.2.公共接口", BUSINESS_CONTROLLER + "global");
    }

    @Bean
    public Docket createSystemApi() {
        return baseDoctor("3.1.权限-系统模块", UPMS_CONTROLLER + "system.controller");
    }

    @Bean
    public Docket createUserApi() {
        return baseDoctor("3.2.权限-用户模块", UPMS_CONTROLLER + "user.controller");
    }

    @Bean
    public Docket createDocsApi() {
        return baseDoctor("3.3.文档模块", DOC_CONTROLLER + "controller");
    }

    @Bean
    public Docket createBusinessApi() {
        return baseDoctor("4.1.业务-业务模块", BUSINESS_CONTROLLER + "business.controller");
    }

    @Bean
    public Docket createAllApi() {
        return baseDoctor("5.1.三方-综合模块", THIRD_CONTROLLER + "all.controller");
    }

    @Bean
    public Docket createWxPubApi() {
        return baseDoctor("5.2.三方-微信公众号模块", THIRD_CONTROLLER + "wxpub.controller");
    }

    @Bean
    public Docket createWxMiniApi() {
        return baseDoctor("5.3.1.三方-微信小程序模块", THIRD_CONTROLLER + "wxmini.controller");
    }

    private Docket baseDoctor(String groupName, String apiPath) {
        return SwaggerUtil.buildDocket(groupName, "接口文档", "v1.0", apiPath);
    }

    /**
     * 增加如下配置可解决Spring Boot  与Swagger 3.0.0 不兼容问题
     **/
    @Bean
    public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
        List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
        Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
        allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
        String basePath = webEndpointProperties.getBasePath();
        EndpointMapping endpointMapping = new EndpointMapping(basePath);
        boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
        return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
    }

    private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
        return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
    }
}